#include "semantics.h"

#include <iostream>

#include "types.h"
#include "utils.h"

#define INFO COLOR(5)

using namespace Utils;

namespace Semantics {
    void Void::Print(int dep) const { Indent(dep), std::cout << INFO "V\n"; }

    void Value::Print(int dep) const {
        Indent(dep), std::cout << INFO << (char)baseType;
        std::cout << "\n";
    }

    void Constant::Print(int dep) const {
        Indent(dep), std::cout << INFO "const " << (char)baseType << " ";
        if (baseType == Type::Basic::Int) {
            std::cout << value.v.i;
        } else if (baseType == Type::Basic::Float) {
            std::cout << value.v.f;
        }
        std::cout << "\n";
    }

    void LValue::Print(int dep) const {
        Indent(dep), std::cout << INFO << (char)baseType << " &";
        if (symbol) std::cout << " (" << symbol << ")";
        std::cout << "\n";
    }

    void Pointer::Print(int dep) const {
        Indent(dep), std::cout << INFO << (char)baseType << " (*&)";
        for (int i = (int)shape.size() - 1; i >= 0; --i)
            std::cout << "[" << shape[i] << "]";
        if (symbol) std::cout << " (" << symbol << ")";
        std::cout << "\n";
    }

    void Function::Print(int dep) const {
        Indent(dep), std::cout << INFO << (char)baseType << "(";
        for (size_t i = 0; i < argType.size(); ++i) {
            if (i) std::cout << ", ";
            auto arg = argType[i];
            std::cout << arg;
        }
        std::cout << ")";
        if (func) std::cout << " (" << func << ")";
        std::cout << "\n";
    }
}  // namespace Semantics